【小ネタ】Redshiftで大量データINSERT時にトランザクションログへの書き込みを回避する方法は?
こんにちは、DI部の川崎です。
Postgresqlでは、Ver. 9.1から「UNLOGGED TABLE」という機能が追加されています。
UNLOGGED TABLE
普通のテーブル、一時テーブル (TEMP TABLE) に加えて、UNLOGGED TABLE というテーブルタイプが追加されました。 UNLOGGED オプションを使うと、挿入 / 更新 / 削除の際にトランザクションログ (WAL) が書かれません。そのため、挿入や更新の多いテーブルを UNLOGGED にすることで、更新処理が大幅に高速化します。 一時テーブルとの違いは、他のセッションからも見えることと、サーバが正常終了する限りはデータが保持されることです。
Let's Postgres 「PostgreSQL 9.1 の新機能」より
http://lets.postgresql.jp/documents/technical/9.1/1#performance
既存のテーブルのレコードを加工して、別のテーブルに挿入する場合は、INSERT INTO ... SELECT構文を使うことが多いと思います。
insert into target_table (select * from source_table);
その場合、トランザクションログへの書き込み処理が発生してしまうと、パフォーマンスの低下を招きます。トランザクションログへの書き込みをスキップすることはできないでしょうか。
データベースのアーキテクチャによっては、同様のことをCREATE TABLE AS SELECT構文を使うことで、トランザクションログをスキップできる場合があると、とある方にアドバイスをもらいました。
Redshiftの場合はどうでしょうか? 早速試してみます。
demo01=# create table ctas_test1 (col1 int); CREATE TABLE demo01=# insert into ctas_test1 values (1); INSERT 0 1 demo01=# begin; ← トランザクションを開始します BEGIN demo01=# create table ctas_test2 as select * from ctas_test1; SELECT demo01=# rollback; ← ロールバックします ROLLBACK demo01=# select * from ctas_test2; ERROR: relation "ctas_test2" does not exist
ロールバックできてしまいました。ということは、トランザクションログが有効である、トランザクションログはスキップされていない、ということになります。
RedshiftはPostgresqlのVer. 8台が基になっているそうです。従って、Ver. 9.1で追加された「UNLOGGED TABLE」の機能は備わっていない訳ですが、大量データを扱うことが多いDWHですので、ぜひトランザクションログへの書き込みを回避できる機能を、実装していただきたいと思います。
もし、別のやり方で回避する方法をご存知の方は、コメント欄からご一報いただけましたら嬉しいです。